package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;

@Controller
@RequestMapping("/")
public class TestExportExcel {
    /**
     *
     * 1,开启一个线程异步从数据库分页获取数据生成EXCEL
     * 2, 使用输入输出管道流，将前端流和本地绑定到一起
     */
    @RequestMapping("/exportExcel")
    public String exportExcel(HttpServletResponse response) throws Exception {
        System.out.println("start request`");
        AtomicBoolean isFin=new AtomicBoolean(false);
        Random random = new Random();
        response.reset();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("multipart/form-data");
        String outfileName = null;
        try {
            outfileName = new String("test.xls".getBytes(), "ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.getMessage());
        }
        response.setHeader("Content-Disposition", "attachment;fileName=" + outfileName);
        //管道输入流
        PipedInputStream pipedInputStream=new PipedInputStream();
        //管道输出流
        PipedOutputStream pipedOutputStream=new PipedOutputStream();

        try {
            pipedInputStream.connect(pipedOutputStream);
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage());
        }

        //新建线程写入数据
        new Thread(()->{
            Long i=0L;
            //模拟从数据库中分页读取数据生成excel
            byte b = new Integer(random.nextInt()).byteValue();
            try {
                while(i<Long.MAX_VALUE) {
                    pipedOutputStream.write(b);
                    pipedOutputStream.flush();
                    i++;

                }
                isFin.compareAndSet(true,false);
            }catch (IOException e){
                throw new RuntimeException(e.getMessage());
            } finally {
                try {
                    pipedInputStream.close();
                } catch (IOException e) {
                   throw new RuntimeException(e.getMessage());
                }

            }
        }).start();
        try {
            while(!isFin.get()) {
                byte[] b = new byte[1024];
                pipedInputStream.read(b);
                response.getOutputStream().write(b);
                response.getOutputStream().flush();
            }
        }finally {
            pipedOutputStream.close();
        }
        return "succ";
    }
}
